package com.sky.chapter3.cas;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author : wushikai
 * <p>
 * date : 2021-03-30
 *
 *   对于Java中的运算操作，例如自增或自减，若没有进行额外的同步操作，在多线程环境下就是线程不安全的;
 *   num++解析为num=num+1，明显，这个操作不具备原子性，多线程并发共享这个变量时必然会出现问题;
 *
 *  自增操作的安全性  -> volatile 不保证原子性 ->    AtomicInteger -> cas 理论 -> sun.misc.Unsafe 类 原理 -> aba 问题 -> 用 AtomicStampedReference 解决aba问题  ;
 *
 */
public class AtomicIntegerTest {

    private static final int THREADS_COUNT = 10;
    public static volatile int count = 0;

    public static void increaseNotAtomic() {
        count++;  //别看只有一行代码, 但是实际上不具有原子性;
    }

    public static void notAtomic( ) {
        Thread[] threads = new Thread[THREADS_COUNT];
        for (int i = 0; i < THREADS_COUNT; i++) {
            threads[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000; i++) {
                        increaseNotAtomic();
                    }
                }
            });
            threads[i].start();
        }

        while (Thread.activeCount() > 2) {
            Thread.yield();
        }
        System.out.println(count);
    }


    public static AtomicInteger atomicInteger = new AtomicInteger(0);

    public static void increaseAtomic() {
        atomicInteger.incrementAndGet();
    }


    /**
     *
     * 但是当使用idea的时候，往往得不到我们想要的结果，在在使用java命令行执行或者eclipse执行却没有这个问题。
     *
     * 经过测试发现，原来在 run main方法时，idea会启动两条线程
     *
     *     Thread[main,5,main]
     *     Thread[Monitor Ctrl-Break,5,main]
     *
     *     主线程 和 idea 监视器线程;
     *
     * 但是 debug 时, 只有
     *     Thread[main,5,main]
     *
     * */
    public static void atomic( ) {
        Thread[] threads = new Thread[THREADS_COUNT];
        for (int i = 0; i < THREADS_COUNT; i++) {
            threads[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000; i++) {
                        increaseAtomic();
                    }
                }
            });
            threads[i].start();
        }
        Thread.currentThread().getThreadGroup().list();


        //必须等所有的线程都执行完毕
        while (Thread.activeCount() > 2) {  // Thread.activeCount() > 1  这个在这里不生效, 甚至导致死锁;
            Thread.yield();
        }
        Thread.currentThread().getThreadGroup().list();
        System.out.println(atomicInteger);
    }

    public static void main(String[] args){
        atomic();
    }



}